package com.yzy.util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class SerialNoGenerator {

    public static String getSerialNo(com.yzy.util.SerialTypeEnum type) {
        return SerialNoGenerator.getInstance().GenerateOrder(type);
    }

    // 使用单例模式，不允许直接创建实例
    private SerialNoGenerator() {
    }

    private static final Map<com.yzy.util.SerialTypeEnum, Long> map = new ConcurrentHashMap<>();

    // 每天最多生成多少订单（最好是像9999这种准备进位的值）
    private static final Long total = 9999L;

    private static String nowDay = null;

    // 格式化的时间字符串
    private static final SimpleDateFormat sdf = new SimpleDateFormat("ss");
    private static final SimpleDateFormat daySdf = new SimpleDateFormat("yyyyMMdd");

    // 创建一个空实例对象，类需要用的时候才赋值
    private static SerialNoGenerator s = null;

    // 单例模式--懒汉模式
    private static synchronized SerialNoGenerator getInstance() {
        if (s == null) {
            s = new SerialNoGenerator();
        }
        return s;
    }

    // 获取当前时间年月日时分秒字符串
    private static String getNowDateStr() {
        return sdf.format(new Date());
    }

    // 获取当前时间年月日
    private static String getNowDayStr() {
        return daySdf.format(new Date());
    }

    /** 随机数规则：缩写+秒+当天排序（4位补全） */
    private synchronized String GenerateOrder(SerialTypeEnum type) {
        // 如果不是同一天，则清空所有的数据，重新计数
        String day = getNowDayStr();
        if (!day.equals(nowDay)) {
            map.clear();
            nowDay = day;
        }

        Long count = map.get(type);
        if (null == count) {
            count = 1L;
        } else {
            count++;
        }
        map.put(type, count);

        String dataStr = getNowDateStr();
        // 算补位
        int countInteger = String.valueOf(total).length() - String.valueOf(count).length();
        // 补字符串
        String bu = "";
        for (int i = 0; i < countInteger; i++) {
            bu += "0";
        }

        bu += String.valueOf(count);
        return type.getShorthand() + dataStr + bu;
//        return type.getShorthand()  + bu;
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread("" + nowDay);
        t.start();
        for (int i= 0 ; i < 10000 ; i++) {
            System.out.println(t.getId() + getSerialNo(SerialTypeEnum.PROJECT));
        }

        Thread.sleep(2000);
        Thread t2 = new Thread("" + nowDay);
        t2.start();
        for (int i= 0 ; i < 10000 ; i++) {
            System.out.println(t2.getId() +  getSerialNo(SerialTypeEnum.PROJECT));
        }
    }

}